import type * as tss from 'typescript/lib/tsserverlibrary';

function init(modules: { typescript: typeof tss }) {
    const typescript = modules.typescript;

    function create(info: tss.server.PluginCreateInfo) {
        const proxy: tss.LanguageService = Object.create(null);
        const logger = info.project.projectService.logger;
        const ls = info.languageService;

        for (let k of Object.keys(info.languageService) as Array<keyof tss.LanguageService>) {
            const x = info.languageService[k]!;
            /*if (k === 'getCompletionsAtPosition') {
                proxy[k] = (fileName: string, position: number, options: tss.GetCompletionsAtPositionOptions | undefined) => {
                    try {
                        // 详细的调试日志
                        logger.info(`[DEBUG] ========== 开始获取补全 ==========`);
                        logger.info(`[DEBUG] 文件名: ${fileName}`);
                        logger.info(`[DEBUG] 位置: ${position}`);
                        logger.info(`[DEBUG] 选项: ${JSON.stringify(options)}`);

                        const original = ls.getCompletionsAtPosition(fileName, position, options);
                        logger.info(`[DEBUG] 原始补全结果: ${original ? original.entries.length : 0} 条`);

                        const sourceFile = ls.getProgram()?.getSourceFile(fileName);
                        if (!sourceFile) {
                            logger.info(`[DEBUG] 错误: 无法获取源文件`);
                            return original;
                        }

                        const text = sourceFile.text;
                        // 获取更多上下文
                        const contextText = text.slice(0, position);
                        const currentToken = text.slice(Math.max(0, position - 2), position);

                        logger.info(`[DEBUG] 上下文文本 (最近10个字符): "${contextText}"`);
                        logger.info(`[DEBUG] 当前标记: "${currentToken}"`);
                        logger.info(`[DEBUG] 当前文本: "${text}"`);
                        logger.info(`[DEBUG] 文本长度: ${text.length}`);
                        logger.info(`[DEBUG] 当前位置: ${position}`);

                        // 检查文件类型
                        const fileExtension = fileName.split('.').pop();
                        logger.info(`[DEBUG] 文件类型: ${fileExtension}`);

                        if (currentToken === 'aa') {
                            logger.info(`[DEBUG] 匹配到 'aa', 准备添加自定义补全`);

                            const customCompletion: tss.CompletionEntry = {
                                name: 'aabb',
                                kind: typescript.ScriptElementKind.constElement,
                                sortText: '0',
                                insertText: 'aabb'
                            };

                            if (!original) {
                                logger.info(`[DEBUG] 没有原始补全结果，创建新的补全列表`);
                                return {
                                    isGlobalCompletion: false,
                                    isMemberCompletion: false,
                                    isNewIdentifierLocation: false,
                                    entries: [customCompletion]
                                };
                            }

                            logger.info(`[DEBUG] 将自定义补全添加到原始列表中`);
                            original.entries.unshift(customCompletion);
                            logger.info(`[DEBUG] 补全列表现在有 ${original.entries.length} 条`);
                        } else {
                            logger.info(`[DEBUG] 未匹配到 'aa', 当前标记为: "${currentToken}"`);
                        }

                        logger.info(`[DEBUG] ========== 补全处理结束 ==========\n`);
                        return original;
                    } catch (error) {
                        logger.info(`[DEBUG] 发生错误: ${error}`);
                        logger.info(`[DEBUG] 错误堆栈: ${(error as Error).stack}`);
                        throw error;
                    }
                };
            } else {
                // @ts-expect-error - JS runtime trickery which is tricky to type tersely
                proxy[k] = (...args: Array<{}>) => {
                    try {
                        // 为关键方法添加调试日志
                        if (['getCompletionEntryDetails', 'getDefinitionAtPosition'].includes(k)) {
                            logger.info(`[DEBUG] 调用方法: ${k}`);
                            logger.info(`[DEBUG] 参数: ${JSON.stringify(args)}`);
                        }
                        // @ts-expect-error
                        const result = x.apply(info.languageService, args);
                        return result;
                    } catch (error) {
                        logger.info(`[DEBUG] 方法 ${k} 执行错误: ${error}`);
                        throw error;
                    }
                };
            }*/
            // @ts-expect-error - JS runtime trickery which is tricky to type tersely
            proxy[k] = (...args: Array<{}>) => {
                try {
                    // 为关键方法添加调试日志
                    if (['getCompletionEntryDetails', 'getDefinitionAtPosition'].includes(k)) {
                        logger.info(`[DEBUG] 调用方法: ${k}`);
                        // logger.info(`[DEBUG] 参数: ${JSON.stringify(args)}`);
                    }
                    // @ts-expect-error
                    const result = x.apply(info.languageService, args);
                    return result;
                } catch (error) {
                    logger.info(`[DEBUG] 方法 ${k} 执行错误: ${error}`);
                    throw error;
                }
            };
        }

        return proxy;
    }

    return { create };
}

export = init;
